`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: Westlake University
// Engineer: shenziyang@westlake.edu.cn
// 
// Create Date: 2021/11/23 20:54:37
// Design Name: HW4
// Module Name: clock_distribution
// Project Name: hw4
// Target Devices: VCU118
// Tool Versions: vivado 2020.1
// Description: Homework 4 for Fudan PLD & HDL courses
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module clock_distribution(
    input clk,              //时钟
    input rst_n,            //复位信号rst_n
    output reg [5:0] F      //输出信号F[5:0]
    );
    
    reg clk_2;
    //step1: 一拍变两拍，由于最小的信号高电平持续时间为2个clk，且2*clk为4*clk的因子，所以需要产生一个新的2*clk时钟控制状态机。
    //注：该方法只是为了简化状态机的状态数。可以想见，若要求的高电平互相之间不存在倍数关系，则对于高电平持续n*clk的信号，需要使用1*clk进行n次状态转换，每次的状态置高相同的信号。这使得状态的数量大大增多。
    always @(posedge clk or negedge rst_n) begin
        if(rst_n) begin //这个初始化非常重要！！！否则clk_2会一直处于X状态
            clk_2 <= 0;
        end
        else
            clk_2 <= ~(clk_2);
    end

    //显式状态机
    reg [3:0]state;              //记录状态机的状态
    always @(posedge clk_2 or negedge rst_n) begin
        if(rst_n) begin          //rst复位重置clk_2, F, state
            F <= 6'b000000;
            state <= 4'b0000;
        end
        else begin
            case (state)
                4'b0000: begin
                    F <= 6'b000001;         //F0高电平2*clk
                    state <= state + 1;
                end
                4'b0001: begin
                    F <= 6'b000010;         //F1高电平4*clk part1
                    state <= state + 1;
                end
                4'b0010: begin
                    F <= 6'b000010;         //F1高电平4*clk part2
                    state <= state + 1;
                end
                4'b0011: begin
                    F <= 6'b000100;         //F2高电平2*clk
                    state <= state + 1;
                end
                4'b0100: begin
                    F <= 6'b001000;         //F3高电平4*clk part1
                    state <= state + 1;
                end
                4'b0101: begin
                    F <= 6'b001000;         //F3高电平4*clk part2
                    state <= state + 1;
                end
                4'b0110: begin
                    F <= 6'b010000;         //F4高电平2*clk
                    state <= state + 1;
                end
                4'b0111: begin
                    F <= 6'b100000;         //F5高电平4*clk part1
                    state <= state + 1;
                end
                4'b1000: begin
                    F <= 6'b100000;         //F5高电平4*clk part2
                    state <= 4'b0000;
                end
                default: begin              //其余状态，回归到state = 0000去
                    F <= 6'b000000;
                    state <= 4'b0000;
                end
            endcase
        end
    end
endmodule
/*
遇到问题：clk_2呈现X状态，状态机不工作
解决方法：在分频电路部分对clk_2做初始化非常重要！
*/
